package com.yhy.wxzn.wcs.device.netty.handler;

import com.yhy.wxzn.wcs.device.netty.bean.HeadData;
import com.yhy.wxzn.wcs.device.netty.bean.SiemensMessage;
import com.yhy.wxzn.wcs.device.netty.enumerate.CommandType;
import com.yhy.wxzn.wcs.device.netty.enumerate.SiemensPLCS;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

@Sharable
public class SiemensHandler extends SimpleChannelInboundHandler<SiemensMessage> {
    private static final Logger log = LoggerFactory.getLogger(SiemensHandler.class);
    private ChannelHandlerContext ctx;
    private HeadData headData = new HeadData();
    private boolean connectd;
    private ChannelPromise promise;
    private SiemensMessage response;

    public SiemensHandler() {
    }

    public boolean isConnectd() {
        return this.ctx != null ? this.ctx.channel().isActive() : false;
    }

    public void setHead(SiemensPLCS type) {
        this.headData.setPlcType(type);
    }

    protected void channelRead0(ChannelHandlerContext ctx, SiemensMessage msg) throws Exception {
        switch(msg.getType()) {
            case Head1:
                this.promise.setSuccess();
                SiemensMessage head1 = new SiemensMessage();
                head1.setType(CommandType.Head2);
                head1.setDataValue(this.headData.getPlcHead2());
                this.sendMessage(head1);
                break;
            case Head2:
                this.connectd = true;
                this.promise.setSuccess();
                break;
            case Read:
            case Write:
                this.response.setSuccess(msg.isSuccess());
                this.response.setMessage(msg.getMessage());
                this.response.setDataValue(msg.getDataValue());
                this.promise.setSuccess();
                break;
            default:
                this.response.setSuccess(false);
                this.response.setDataValue((ByteBuf)null);
                this.response.setMessage(msg.getMessage());
        }

    }

    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        this.ctx = ctx;
        this.connectd = false;
        SiemensMessage msg = new SiemensMessage();
        msg.setType(CommandType.Head1);
        msg.setDataValue(this.headData.getPlcHead1());
        this.sendMessage(msg);
    }

    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        this.connectd = false;
        log.error("当前连接中断!");
    }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        this.connectd = false;
        ctx.close();
    }

    public synchronized ChannelPromise sendMessage(SiemensMessage message) {
        while(this.ctx == null) {
            try {
                TimeUnit.MILLISECONDS.sleep(1L);
                log.error("等待ChannelHandlerContext实例化");
            } catch (InterruptedException var3) {
                log.error("等待ChannelHandlerContext实例化过程中出错:" + var3.getMessage());
            }
        }

        this.response = new SiemensMessage();
        this.response.setType(message.getType());
        this.response.setByte(message.isByte());
        this.response.setDataValue(message.getDataValue());
        this.response.setDataLength(message.getDataLength());
        this.response.setDataAddress(message.getDataAddress());
        this.response.setDataType(message.getDataType());
        this.response.setDbBlockNo(message.getDbBlockNo());
        this.response.setFnCode(message.getFnCode());
        this.promise = this.ctx.newPromise();
        this.ctx.writeAndFlush(message);
        return this.promise;
    }

    public SiemensMessage getResponse() {
        return this.response;
    }
}
